package com.mainworks.template.service.security.impl;

import com.mainworks.commons.UnifyResponse;
import com.mainworks.commons.config.component.JwtTokenUtil;
import com.mainworks.commons.enums.ResponseCode;
import com.mainworks.commons.redis.RedisUtils;
import com.mainworks.commons.utils.IPInetAddress;
import com.mainworks.template.params.LoginParams;
import com.mainworks.template.service.security.SecurityUserDetailsService;
import com.mainworks.template.service.security.UserLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;

/**
 * 用户登录业务层
 * @Author: HuangMinJie
 * @CreateDate: 2021/10/31 15:28
 * @Description:
 * @Version: 1.0.0.0
 * @ModifiedBy:
 * @ModifiedDate:
 * @ModifiedDescription:
 */
@Service
public class UserLoginServiceImpl implements UserLoginService {
    @Autowired
    private SecurityUserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    /**
     * 用户登录业务处理类
     *@Author: HuangMinJie
     *@param  params
     *@CreateDate:  2021/10/31 15:46
     *@Description:
     */
    @Override
    public UnifyResponse login(LoginParams params, HttpServletRequest request) {
        RedisUtils redisUtils=new RedisUtils();
        redisUtils.redisTemplates = redisTemplate;
        JSONObject data=new JSONObject();
        String ip = IPInetAddress.getIpAddress(request);
        String captcha = redisUtils.getHash("Login_Captcha",ip);
        if (captcha!=null&&!"".equals(captcha)){
            if (params.getCode()!=null&&!captcha.equals(params.getCode())){
                return UnifyResponse.error(ResponseCode.FAIL,"验证码不正确");
            }
        }
        String nullUser = redisUtils.getHash("Null_User",ip);
        if (nullUser==null||"".equals(nullUser)){
            nullUser = "0";
        }
        String login_fail = redisUtils.getHash("Login_Fail",ip);
        if (login_fail==null||"".equals(login_fail)){
            login_fail = "0";
        }
        int count = Integer.parseInt(login_fail.trim());
        if (count>10){
            return UnifyResponse.error(ResponseCode.FAIL,"登录失败次数太多,请明天再试");
        }
        int nullCount = Integer.parseInt(nullUser.trim());
        if (nullCount>30){
            return UnifyResponse.error(ResponseCode.FAIL,"由于你过多的输入空的用户名,系统拒绝你的登录。");
        }
        UserDetails userDetails= userDetailsService.loadUserByUsername(params.getUsername());
        if (userDetails ==null){

            count ++;
            redisUtils.put("Login_Fail",ip,String.valueOf(count));
            if (count>5){
                captcha = IPInetAddress.createCaptcha();
                redisUtils.put("Login_Captcha",ip,captcha);
            }
            redisUtils.put("Null_User",ip,String.valueOf(count));
            return UnifyResponse.error(ResponseCode.FAIL,"用户名或密码错误");
        }
        if (!passwordEncoder.matches(params.getPassword(),userDetails.getPassword())){
            count ++;
            redisUtils.put("Login_Fail",ip,String.valueOf(count));
            if (count>5){
                captcha = IPInetAddress.createCaptcha();
                redisUtils.put("Login_Captcha",ip,captcha);
            }
            return UnifyResponse.error(ResponseCode.FAIL,"用户名或密码错误");
        }
        redisUtils.hashDelete("Login_Captcha",ip);
        redisUtils.hashDelete("Login_Fail",ip);
        redisUtils.hashDelete("Null_User",ip);
        //更新security登录用户对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails
                ,null,userDetails.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //生成token
        String token = jwtTokenUtil.generateToken(userDetails);
        JSONObject tokenMap = new JSONObject();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);
        return UnifyResponse.success(tokenMap);
    }
}
